<?php

declare (strict_types=1);

namespace app\command;

use app\common\exception\LogicException;
use app\common\service\rabbitMQ\RabbitMQ;
use app\common\service\rabbitMQ\OrderCreated;
use app\common\service\rabbitMQ\OrderPaymentTimedOut;
use app\common\service\rabbitMQ\UserCouponExpiredCheck;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

class Consumer extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('Consumer')->addOption(
            'action',
            null,
            Option::VALUE_REQUIRED,
            '消费者Action'
        )->setDescription('消费者');
    }

    /**
     * @param Input $input
     * @param Output $output
     * @return int|void|null
     * @throws \ErrorException
     */
    protected function execute(Input $input, Output $output)
    {
        $action = trim($input->getOption('action'));
        switch ($action) {
            case 'OrderCreated':
                $rabbitMQ    = OrderCreated::instance();
                $consumerTag = 'No.1';
                $rabbitMQ->consumer(
                    $consumerTag,
                    static function ($message) {
                        try {
                            $body = unserialize($message->body);
                            print_r($body);

                            #幂等性操作，解决重复消费的问题
                            if (!$mModel = RabbitMQ::messageIdempotence($message)) {
                                //已经处理过
                                $message->ack();
                            }
                            #消费核心方法
                            if (OrderCreated::consumer($body)) {
                                print_r($body);
                                $message->ack();
                            }
                            else {
                                $mModel->force()->delete();
                                $message->nack(true);
                            }
                        } catch (\Exception $e) {
                            $message->nack(true);
                            throw $e;
                        }
                    }
                );
                break;
            case 'OrderPaymentTimedOut':
                $rabbitMQ    = OrderPaymentTimedOut::instance();
                $consumerTag = 'No.1';
                $rabbitMQ->consumer(
                    $consumerTag,
                    static function ($message) {
                        try {
                            $body = unserialize($message->body);
                            print_r($body);

                            #幂等性操作，解决重复消费的问题
                            if (!$mModel = RabbitMQ::messageIdempotence($message)) {
                                //已经处理过
                                $message->ack();
                            }
                            #消费核心方法
                            if (OrderPaymentTimedOut::consumer($body)) {
                                print_r($body);
                                $message->ack();
                            }
                            else {
                                $mModel->force()->delete();
                                $message->nack(true);
                            }
                        } catch (\Exception $e) {
                            $message->nack(true);
                            throw $e;
                        }
                    }
                );
                break;
            case 'UserCouponExpiredCheck':
                $rabbitMQ    = UserCouponExpiredCheck::instance();
                $consumerTag = 'No.1';
                $rabbitMQ->consumer(
                    $consumerTag,
                    static function ($message) {
                        try {
                            $body = unserialize($message->body);
                            print_r($body);

                            #幂等性操作，解决重复消费的问题
                            if (!$mModel = RabbitMQ::messageIdempotence($message)) {
                                //已经处理过
                                $message->ack();
                            }
                            #消费核心方法
                            if (UserCouponExpiredCheck::consumer($body)) {
                                print_r($body);
                                $message->ack();
                            }
                            else {
                                $mModel->force()->delete();
                                $message->nack(true);
                            }
                        } catch (\Exception $e) {
                            $message->nack(true);
                            throw $e;
                        }
                    }
                );
                break;
            default:
                print_r('消费者' . $action . '不存在');
        }
    }
}